package com.ebt.m.customer.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.ebt.m.R;

/**
 * created by rick.wang
 */
public class BadgeView extends View {

    public static final int[] COLORS = new int[]{ 0xffff0000, 0xfffccc67, 0xfff88db9};
    private int innerColor = 0;
    private int textSize = 0;
    private float bendWidth;
    private float bendHeight;
    private float width;
    private float height;
    private int paintStyle = PAINT_STYLE_FILL;

    private static final int PAINT_STYLE_FILL = 0;
    private static final int PAINT_STYLE_STROKE = 1;

    private int style;
    private String text;
    private int paddingHorizontal = 0;
    private int paddingVertical = 0;
    private int minH = 0;
    private int minW = 0;
    private int outerColor = 0;
    private int outerWidth = 0;

    private RectF rectf = new RectF();
    private float textCenterYOffset;

    private Path path = new Path();
    private Paint paintBg = new Paint();
    private Paint paintTxt = new Paint();

    public BadgeView(Context context) {
        super(context);
        init();
    }
    public BadgeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttr(context, attrs);
        init();
    }
    public BadgeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context, attrs);
        init();
    }

    private void initAttr(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BadgeView);
        if(a == null){
            return;
        }
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.BadgeView_bv_BackgroundColor:
                    innerColor = a.getColor(attr, COLORS[0]);
                    break;
                case R.styleable.BadgeView_bv_TextSize:
                    textSize = a.getDimensionPixelSize(attr, sp2px(getContext(), 14));
                    break;
                case R.styleable.BadgeView_bv_Style:
                    style = a.getInt(attr, 0);
                    break;
                case R.styleable.BadgeView_bv_Text:
                    text = a.getString(attr);
                    break;
                case R.styleable.BadgeView_bv_PaddingHorizontal:
                    paddingHorizontal = a.getDimensionPixelSize(attr, dp2px(getContext(), 6));
                    break;
                case R.styleable.BadgeView_bv_PaddingVertical:
                    paddingVertical = a.getDimensionPixelSize(attr, dp2px(getContext(), 3));
                    break;
                case R.styleable.BadgeView_bv_MinH:
                    minH = a.getDimensionPixelSize(attr,dp2px(getContext(), 1));
                    break;
                case R.styleable.BadgeView_bv_MinW:
                    minW = a.getDimensionPixelSize(attr,dp2px(getContext(), 1));
                    break;
                case R.styleable.BadgeView_bv_OuterColor:
                    outerColor = a.getColor(attr, 0x00000000);
                    break;
                case R.styleable.BadgeView_bv_OuterWidth:
                    outerWidth = a.getDimensionPixelSize(attr,dp2px(getContext(), 1));
                    break;
            }
        }
        a.recycle();
    }

    private void init(){
        if(innerColor == 0){
            innerColor = COLORS[0];
        }
        if(textSize == 0){
            textSize = sp2px(getContext(), 12);
        }
        if(paddingHorizontal == 0){
            paddingHorizontal = dp2px(getContext(), 6);
        }
        if(paddingVertical == 0){
            paddingVertical = dp2px(getContext(), 3);
        }

        paintBg.setAntiAlias(true);
        if(paintStyle == PAINT_STYLE_FILL) {
            paintBg.setStyle(Paint.Style.FILL);
        }else{
            paintBg.setStyle(Paint.Style.STROKE);
        }
        paintBg.setColor(innerColor);

        paintTxt.setAntiAlias(true);
        paintTxt.setTextAlign(Paint.Align.CENTER);
        paintTxt.setTextSize(textSize);
        paintTxt.setColor(0xffffffff);

        textCenterYOffset = getTextCenterYOffset(paintTxt.getFontMetrics());
    }

    private float getTextCenterYOffset(Paint.FontMetrics fontMetrics){
        if(fontMetrics == null) return 0;
        return Math.abs(fontMetrics.top + fontMetrics.bottom)/2;
    }

    public void setColorType(int type){
        int newColor = COLORS[Math.abs(type) % COLORS.length];
        if(newColor != innerColor){
            innerColor = newColor;
            invalidate();
        }
    }

    public void setStyle(int style){
        this.style = style;
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureWidth(widthMeasureSpec, paintTxt),
                measureHeight(heightMeasureSpec, paintTxt));
    }

    private int measureWidth(int measureSpec, Paint paint) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            int widthA = getTextWidth(text, paint) + 2 * paddingHorizontal;
            widthA = Math.max(widthA, minW);

            result = this.getPaddingLeft() + this.getPaddingRight() + widthA;//MeasureSpec.UNSPECIFIED
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int measureHeight(int measureSpec, Paint paint) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            int heightA = getTextHeight(text, paint) + 2 * paddingVertical;
            heightA = Math.max(heightA, minH);

            result = this.getPaddingTop() + this.getPaddingBottom() + heightA;//MeasureSpec.UNSPECIFIED
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    private int getTextWidth(String text, Paint paint){
        if(!TextUtils.isEmpty(text)){
            return (int)(paint.measureText(text) + 0.5f);
        }
        return -1;
    }

    private int getTextHeight(String text, Paint paint){
        if(!TextUtils.isEmpty(text)){
            Rect textBounds = new Rect();
            paint.getTextBounds(text, 0, text.length(), textBounds);
            return textBounds.height();
        }
        return -1;
    }

    private int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    private int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        path.reset();
        if(style == 0){
            rectf.left = getPaddingLeft();
            rectf.top = getPaddingTop();
            rectf.bottom = height - getPaddingBottom();
            rectf.right = rectf.left + rectf.bottom - rectf.top;
        }

        path.moveTo(rectf.centerX(), rectf.bottom);
        path.arcTo(rectf, 90, 180);
        path.lineTo(width - getPaddingRight() - rectf.width() / 2, rectf.top);
        rectf.offsetTo(width - getPaddingRight() - rectf.width(), rectf.top);
        path.arcTo(rectf, -90, 180);
        path.close();
        canvas.drawPath(path, paintBg);
        if (text == null){
            text = "";
        }
        canvas.drawText(text, getPaddingLeft() + (width - getPaddingLeft() - getPaddingRight())/2,
                getPaddingTop() + (height - getPaddingTop() - getPaddingBottom())/2 + textCenterYOffset, paintTxt);
    }

    public void setText(String text){
        if (isStringEqual(this.text, text)){
            return;
        }
        this.text = text;
        requestLayout();
    }

    private boolean isStringEqual(String a, String b){
        if (a == null && b == null){
            return true;
        }
        if (a != null){
            return a.equals(b);
        }else{
            return b.equals(a);
        }
    }
}